#ifndef __BASE_DEFINE_H__
#define __BASE_DEFINE_H__

#include <ros/ros.h>
#include <ros/package.h>
#include <tf2_ros/transform_listener.h>
#include <tf2/LinearMath/Quaternion.h>
#include <tf2/LinearMath/Matrix3x3.h>
#include <tf2_geometry_msgs/tf2_geometry_msgs.h>
#include <tf2/utils.h>
#include <std_msgs/String.h>
#include <std_msgs/Bool.h>
#include <std_msgs/Empty.h>
#include <std_srvs/SetBool.h>
#include <geometry_msgs/PoseStamped.h>
#include <geometry_msgs/Point32.h>
#include <geometry_msgs/PoseStamped.h>
#include <nav_msgs/MapMetaData.h>
#include <nav_msgs/OccupancyGrid.h>
#include <nav_msgs/Path.h>
#include <cln_msgs/StringArray.h>
#include <cln_msgs/LogMsg.h>
#include <cln_msgs/VoiceOutput.h>
#include <cln_msgs/CleanTask.h>
#include <cln_msgs/MapStatus.h>
#include <cln_msgs/HardwareState.h>
#include <cln_msgs/AlarmMsg.h>
#include <v3_msgs/TaskType.h>
#include <v3_msgs/EdgeMode.h>
#include <v3_msgs/TaskControlMode.h>
#include <v3_msgs/TaskSpeed.h>
#include <v3_msgs/TaskState.h>
#include <v3_msgs/PathGenerateType.h>
#include <v3_msgs/PathGenerateAction.h>
#include <v3_msgs/DeviceType.h>
#include <v3_msgs/TaskPath.h>
#include <v3_msgs/TaskBase.h>
#include <v3_msgs/TaskEcho.h>
#include <v3_msgs/TaskSingle.h>
#include <v3_msgs/TaskGroup.h>
#include <v3_msgs/TimerTask.h>
#include <v3_msgs/OnlineTask.h>
#include <v3_msgs/TaskSingleManager.h>
#include <v3_msgs/TaskGroupManager.h>
#include <v3_msgs/TimerTaskManager.h>
#include <v3_msgs/TaskPicture.h>
#include <v3_msgs/TaskRecord.h>
#include <v3_msgs/PathGenerate.h>
#include <v3_msgs/MapStatus.h>
#include <v3_msgs/MapInfo.h>
#include <v3_msgs/MapList.h>
#include <v3_msgs/TaskReportManager.h>
#include <v3_msgs/TaskGenerateManager.h>
#include <v3_msgs/GoHome.h>
#include <v3_msgs/P2PMove.h>
#include <v3_msgs/OnlineTaskCtrl.h>
#include <v3_msgs/TaskFinishedRecord.h>
#include <v3_msgs/TaskControllerManager.h>
#include <v3_msgs/PathGenerateManager.h>
#include <v3_msgs/MapInfoRequest.h>
#include <v3_msgs/CloudSyncTaskReportManager.h>

#include <iostream>
#include <locale>
#include <algorithm>
#include <functional>
#include <deque>
#include <unordered_map>
using namespace std;

// 定义反馈状态
struct Status{
    bool success = true;
    string message = "OK";
    long err_code = 0X000000;
};


// 任务报告参数配置
struct TaskReportConfig{
    int coverage_threshold = 60;
    unordered_map<long, vector<string>> reasons_translation_list;   //例如 0x050101 [cn, ]
    unordered_map<string, long> error_code_map;         //例如 user_cancel 0x050102
};


// 任务图像数据
struct TaskPicture{
    string png_file_path;    //图片存储路径
    string png_str;          //图片二进制字符串
    string qiniu_file_key;   //七牛云存储key
    string map_name;          //地图名称
};

// 定义任务类型
enum class TaskType{
    UNKNOWN = 0,          //未知
    CHARGING_TASK = 1,    //回桩任务
    P2P_TASK = 2,         //P2P任务
    TEACH_TASK = 3,       //示教任务
    SWEEP_TASK = 4,       //清扫任务
    // EDGE_TASK = 5,      //贴边任务
    ELEVATOR_TRANS_TASK = 6  //梯控转移任务
};

// 定义任务状态
enum class TaskState{
    UNKNOWN = 0,      //未知状态
    IDLE  = 1,        //空闲状态
    EXECUING = 2,     //执行状态
    PAUSE = 11,       //暂停状态(人为点击暂停按钮)
    BLOCKED = 12,     //阻塞状态（自动判断，如进入手动、急停）
    //int RESUME = 13,     //恢复状态
    FINISHED = 21,      //正常结束状态
    USER_CANCEL = 23,   //用户取消状态
    TERMINATED = 24,    //终止状态，如插入回桩任务，当前任务将被终止
    ERROR = 100      //异常状态，非正常结束
};

// 定义贴边模式
enum class EdgeMode{
    UNKNOWN = 0,            //未知
    EDGE_ZERO_MODE = 11,    //零贴边模式
    EDGE_5CM_MODE = 12      //5CM贴边模式
};

// 定义任务控制模式
enum class TaskControlMode{
    UNKNOWN = 100,                      //未知
    SWEEP_STANDARD_MODE = 0,            //标准清扫模式
    SWEEP_EDGE_MODE = 10,               //贴边清扫模式
    SWEEP_STANDARD_AND_EDGE = 11,       //标准+贴边清扫模式
    SWEEP_STANDARD_AND_REPAIR = 21,  //标准+补漏清扫模式
    FOLLOW_MODE = 31,                   //跟随模式  
    // P2P_MODE = 32,                   //P2P模式
    // CHARGING_MODE = 33,              //回桩模式
    // ELEVATOR_TRANS_MODE = 41,        //梯控转移模式
};

// 定义任务速度
enum class TaskSpeed{
    LOW_SPEED = 0,       //低速
    MIDDLE_SPEED = 1,    //中速
    HIGH_SPEED = 2,      //高速
};

// 定义任务路径生成方式
enum class PathGenerateType{
    BOUSTROPHEDON_METHOD = 0,       //弓字型
    ARC_BOUSTROPHEDON_METHOD = 1,   //弓弧类型
    WRAPPER_METHOD =  2,            //回字类型
    EDGE_METHOD = 3,                //贴边类型
    P2P_METHOD = 4,                 //点对点类型
    MANUAL_METHOD = 5,              //手推路线类型
    MANUAL_POLYGON_METHOD = 6,      //手推区域类型
    AUTO_METHOD = 10,               //自适应
    UNKNOWN = 100,                  //位置
};

// 定义任务路径生成动作
enum class PathGenerateAction{
    UNKNOWN = 0,            //未知
    START_RECORD = 1,       //开始记录
    FINISHED_RECORD = 2,    //结束记录
    CANCEL_RECORD = 3       //取消记录
};

// 定义清洁设备类型
enum class DeviceType{
    SWEEP_DEVICE = 0, //扫地设备
    WASH_DEVICE = 1  //洗地设备
};

// 定义任务路径
struct TaskPath{
    PathGenerateType path_type = PathGenerateType::UNKNOWN;          //路径类型
    vector<geometry_msgs::Pose> poses;   //任务路径
    float path_interval = 0.0;                 //用于清扫覆盖率中路径宽度
};

// 路径请求生成属性
struct PathGenerate{
    vector<PathGenerateType> path_types = {};   //路径类型
    vector<PathGenerateType> path_types_child = {};   //路径类型
    // PathGenerateType path_type = PathGenerateType::UNKNOWN;         //路径类型
    // PathGenerateType path_type_child = PathGenerateType::UNKNOWN;   //二级路径类型，目前只用于手推区域类型
    PathGenerateAction path_action = PathGenerateAction::UNKNOWN;     //路径动作，仅用于手推路径类型
    bool using_map = false;                     //是否使用地图
    int offset = 0.0;                         //动态路径偏移量 0-无偏移 >0 偏移值，单位cm
    // bool cancel_polygon_inflation = false;      //取消多边形轮廓膨胀处理，仅在手推区域置为True
    vector<v3_msgs::PolygonData> danger_areas;      //危险区域 兼容以前数据结构，后续确定是否可删除
};

// 定义任务基础属性
struct TaskBase{
    string task_name = "";   //任务名称
    string task_id = "";     //任务id
    v3_msgs::MapBase map_base;          //所属地图基础属性
    v3_msgs::MapBase next_map_base;     //下个地图基础属性，用于梯控转移任务
    string group_name = "";             //所属组合任务名称
    string group_id = "";               //所属组合任务id
    TaskType task_type = TaskType::UNKNOWN;      //任务类型
    geometry_msgs::Pose start;        //任务起点
    //geometry_msgs/Pose end          //任务终点(待讨论)
    v3_msgs::PolygonData polygon;     //任务轮廓 顺时针，闭合多边形
    DeviceType device_type = DeviceType::SWEEP_DEVICE;         //设备类型
    TaskControlMode control_mode = TaskControlMode::UNKNOWN;   //执行模式
    EdgeMode edge_mode = EdgeMode::EDGE_ZERO_MODE;             //贴边执行模式
    TaskSpeed task_speed = TaskSpeed::LOW_SPEED;               //任务速度
    vector<TaskPath> paths;                 //任务路径
    vector<TaskPath> edge_paths;            //贴边路径
    geometry_msgs::Pose pose;               //位姿 P2P任务和回桩任务使用
    bool dynamic_adjust_path = false;       //路径动态调整
    string utils_mode = "";                 //用户自定义外设执行模式
    float estimated_time = 0.0;             //任务预估耗时 单位秒
    float estimated_distance = 0.0;         //预计清洁距离 ：所有单任务的覆盖路径总长度   
    float estimated_speed = 0.0;            //预计清洁速度 ：以用户配置的清洁速度的70%作为预估清洁速度
    float estimated_efficiency = 0.0;       //预计清洁效率 ：预估清洁面积/预估清洁时间      
    float task_area = 0.0;                  //总清扫面积
    PathGenerate path_gen;                  //路径生成属性
    bool is_top = false;                    //置顶操作
    bool is_assigned = false;               //任务已指派下发
};


// 定义任务回传状态
struct TaskEcho{
    string task_name = "";       //任务名称
    string task_id = "";         //任务id
    string add_time = "";        //添加时间
    string start_time = "";      //开始执行时间
    string end_time = "";        //结束执行时间
    float progress = 0.0;        //当前任务进度
    float working_time = 0.0;               //实际执行耗时 单位秒
    float coverage_rate = 0.0;              //覆盖率
    float cleaned_area = 0.0;               //已清洁面积
    float real_average_speed = 0.0;          //实际清洁平均速度：实际清洁行驶距离/实际清洁时间
    float real_travel_dist = 0.0;            //实际清洁行驶距离 ：基于定位变化累加值
    float avoidance_obstacle_number = 0.0;   //避障次数
    float extrication_number = 0.0;          //脱困次数
    float extrication_time = 0.0;            //脱困时间
    float missed_area = 0.0;                 //补漏面积
    float missed_number = 0.0;               //补漏区域数量
    float missed_time = 0.0;                 //补漏时间
    TaskPath cleaned_path;                  //已清洁路径
    v3_msgs::ErrorCode error_code;          //错误码
    TaskState task_status = TaskState::UNKNOWN;          //任务状态
    TaskPicture task_picture;               //任务图片 保留字段，暂未使用
};

// 定义单任务属性
struct TaskSingle{
    TaskBase task_base;
    TaskEcho task_echo;
};

// 定义组任务属性
struct TaskGroup{
    string group_name = "";         //组合任务名称
    string group_id = "";           //运行时生成
    string timertask_name = "";     //所属定时任务名称
    string timertask_id = "";       //所属定时任务id
    vector<TaskSingle> task_list; //任务列表
    bool is_top = false; 
};


// 定义定时任务属性
struct TimerTask{
    string timertask_name = "";
    string timertask_id = "";           //运行时生成
    bool enable = false;                //使能开关
    string start_time = "";             //开始执行时间  09-30
    string forced_end_time = "";        //强制结束时间
    bool forced_end_time_enable = false;    //强制结束使能开关
    vector<int> timetable;              //时刻表 周一到周日
    vector<TaskGroup> taskgroup_list;   //组合任务列表
    float estimated_time = 0.0;         //预估总耗时
    bool is_top = false;
    bool multi_maps_shared = false;     //多地图共用定时任务
    string map_name = "";               //非共享定时任务，需要添加地图名称
};

// 定义在线任务属性
struct OnlineTask{
    vector<TaskGroup> taskgroup_list;   //组合任务列表
};

// 任务记录数据
struct TaskRecord{
    TaskGroup task_group;                         //任务组数据
    bool is_assigned = false;                     //任务已指派下发
    string add_time = "";                         //添加时间
    string start_time = "";                       //开始执行时间
    string end_time = "";                         //结束执行时间
    float working_time = 0.0;                     //实际执行耗时 单位秒
    float total_area = 0.0;                       //总清洁面积
    float cleaned_area = 0.0;                     //已清洁面积
    float uncleaned_area = 0.0;                   //未清扫面积：工作总面积➖工作面积
    float cleaning_efficiency = 0.0;              //清洁效率：工作面积➗工作时长 
    float coverage_rate = 0.0;                    //覆盖率：工作面积➗工作总面积
    v3_msgs::ErrorCode error_code;                //错误码
    TaskState status = TaskState::UNKNOWN;   //任务组状态
    vector<TaskPicture> task_pictures;      //任务图片 每个地图生成一张图片
};

// 工作语音
struct WorkVoice{
    bool enable = false;         //默认使能关
    string voice_data = "";      //播报语音词
    int frequency = 60;          //播报频率，单位s
    ros::Time last_pub_time = ros::Time(0);     //上次播报时间
};

#endif